package com.jie.netty.processor;

import com.jie.constants.ChannelAttrKey;
import com.jie.constants.IMRedisKey;
import com.jie.constants.RedisSessionConstants;
import com.jie.netty.IMServerGroup;
import com.jie.netty.contant.IMConstant;
import com.jie.netty.im.UserChannelCtxMap;
import com.jie.netty.model.IMSendInfo;
import com.jie.netty.type.IMCmdType;
import com.jie.utils.JwtTokenUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 * 登录消息 发送这里要验证一次jwt
 * @Author: 杰
 * @Project :net-disk
 * @DateTime: 2024/7/2 14:30
 **/
@Slf4j
@Component
public class LoginProcessor extends AbstractMessageProcessor<String>{

    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 主要将用户添加到channel中
     * @param authHeader
     */
    @Override
    public synchronized void process(ChannelHandlerContext ctx,String authHeader) {
        //判断当前用户的jwt是否有效
        //如果有效，则将用户添加到channel中
        if (authHeader!=null && authHeader.startsWith(tokenHead)){
            //截取authtoken
            String authToken = authHeader.substring(tokenHead.length());
            //根据token得到用户名
            String username = jwtTokenUtil.getUsernameFromToken(authToken);
            Integer terminal=0;
            //效验失败关闭channel
             if (null==username){
                ctx.channel().close();
                log.warn("用户token校验不通过，强制下线,token:{}", authToken);
            }
            // 绑定用户和channel
            UserChannelCtxMap.addChannelCtx(username, terminal, ctx);
            // 设置用户id属性
            AttributeKey<String> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_NAME);
            ctx.channel().attr(userIdAttr).set(username);
            // 设置用户终端类型
            AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
            ctx.channel().attr(terminalAttr).set(terminal);
            //设置公共属性来判断是登陆还是房间
            AttributeKey<String> publicAttr = AttributeKey.valueOf(ChannelAttrKey.PUBLIC_INFO);
            ctx.channel().attr(publicAttr).set(ChannelAttrKey.LOGIN_INFO);
            // 初始化心跳次数
            AttributeKey<Long> heartBeatAttr = AttributeKey.valueOf("HEARTBEAt_TIMES");
            ctx.channel().attr(heartBeatAttr).set(0L);
            // 在redis上记录每个user的channelId，15秒没有心跳，则自动过期
            String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, username, terminal.toString());
            redisTemplate.opsForValue().set(key, IMServerGroup.serverId, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS);
            // 响应ws
            IMSendInfo<Object> sendInfo = new IMSendInfo<>();
            sendInfo.setCmd(IMCmdType.LOGIN.code());
            sendInfo.setData(username);
            ctx.channel().writeAndFlush(sendInfo);
        }
    }
}
